package com.huiminpay.merchant.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.domain.PageVO;
import com.huiminpay.merchant.convert.MerchantCovert;
import com.huiminpay.merchant.convert.StaffConvert;
import com.huiminpay.merchant.convert.StoreConvert;
import com.huiminpay.merchant.dto.MerchantDTO;
import com.huiminpay.merchant.dto.StaffDTO;
import com.huiminpay.merchant.dto.StoreDTO;
import com.huiminpay.merchant.entity.Merchant;
import com.huiminpay.merchant.entity.Staff;
import com.huiminpay.merchant.entity.Store;
import com.huiminpay.merchant.entity.StoreStaff;
import com.huiminpay.merchant.mapper.MerchantMapper;
import com.huiminpay.merchant.mapper.StaffMapper;
import com.huiminpay.merchant.mapper.StoreMapper;
import com.huiminpay.merchant.mapper.StoreStaffMapper;
import com.huiminpay.user.api.TenantService;
import com.huiminpay.user.api.dto.tenant.CreateTenantRequestDTO;
import com.huiminpay.user.api.dto.tenant.TenantDTO;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class MerchantServiceImpl implements IMerchantService {
    @Autowired
    MerchantMapper merchantMapper;
    @Autowired
    StoreMapper storeMapper;
    @Autowired
    StaffMapper staffMapper;
    @Autowired
    StoreStaffMapper storeStaffMapper;
    @Reference
    TenantService tenantService;

    @Override
    public MerchantDTO findById(Long id) {
        Merchant merchant = merchantMapper.selectById(id);

//        MerchantDTO merchantDTO = new MerchantDTO();
//        BeanUtils.copyProperties(merchant,merchantDTO);
        return MerchantCovert.INSTANCE.entity2dto(merchant);
    }

    @Override
    public MerchantDTO regMerchant(MerchantDTO merchantDTO) throws  BusinessException{
        // 是否需要非空校验

//        Merchant merchant = new Merchant();

        // 手机号必须唯一
        LambdaQueryWrapper<Merchant> qw = new LambdaQueryWrapper<Merchant>();
        qw.eq(Merchant::getMobile,merchantDTO.getMobile());
        Integer integer = merchantMapper.selectCount(qw);
        if(integer>0){
//            throw new RuntimeException("手机号已注册");
            throw new BusinessException(CommonErrorCode.E_200203);
        }

        // 2.调用SaaS接口   添加 租户 并绑定  和   门店  员工   商户 之间的关系
        /**
         *  创建账号并且初始化权限
         1、手机号

         2、账号

         3、密码

         4、租户类型：huimin-merchant

         5、默认套餐：huimin-merchant

         6、租户名称，同账号名

         */
        CreateTenantRequestDTO createTenantRequestDTO = new CreateTenantRequestDTO();
        createTenantRequestDTO.setBundleCode("huimin-merchant");
        createTenantRequestDTO.setMobile(merchantDTO.getMobile());
        createTenantRequestDTO.setName(merchantDTO.getUsername());
        createTenantRequestDTO.setPassword(merchantDTO.getPassword());
        createTenantRequestDTO.setUsername(merchantDTO.getUsername());
        createTenantRequestDTO.setTenantTypeCode("huimin-merchant");
        TenantDTO tenantDTO = tenantService.createTenantAndAccount(createTenantRequestDTO);

        /**
         * 业务参数设置
         */
//        BeanUtils.copyProperties(merchantDTO,merchant);
        Merchant merchant = MerchantCovert.INSTANCE.dto2entity(merchantDTO);
        merchant.setAuditStatus("0");
        merchant.setTenantId(tenantDTO.getId());
        merchantMapper.insert(merchant);

        // 创建门店
        StoreDTO storeDTO = new StoreDTO();
        storeDTO.setMerchantId(merchant.getId());
        storeDTO.setParentId(0L);
        storeDTO.setStoreName("根门店");
        storeDTO.setStoreStatus(true);
        StoreDTO store = this.createStore(storeDTO);

        // 创建员工
        StaffDTO staffDTO = new StaffDTO();
        staffDTO.setMerchantId(merchant.getId());
        staffDTO.setMobile(merchantDTO.getMobile());
        staffDTO.setUsername(merchantDTO.getUsername());
        staffDTO.setStoreId(store.getId());
        staffDTO.setStaffStatus(true);
        StaffDTO staff = this.createStaff(staffDTO);

        // 给门店设置管理员
        this.bindStaffToStore(store.getId(),staff.getId());

//        BeanUtils.copyProperties(merchant,merchantDTO);
        return MerchantCovert.INSTANCE.entity2dto(merchant);
    }

    @Override
    public MerchantDTO applyMerchant(Long merchantId, MerchantDTO merchantDTO) throws BusinessException{
        // 1.非空校验
        if(merchantId==null){
            throw new BusinessException(CommonErrorCode.E_200201);
        }

        // 2.判断更新的商户是否存在
        Merchant merchant = merchantMapper.selectById(merchantId);
        if(merchant==null){
            throw new BusinessException(CommonErrorCode.E_200227);
        }

        // 更新资料
        merchantDTO.setId(merchantId);
        // 隐藏业务信息
        //审核状态 0-未申请,1-已申请待审核,2-审核通过,3-审核拒绝
        merchantDTO.setAuditStatus("1");
        merchantMapper.updateById(MerchantCovert.INSTANCE.dto2entity(merchantDTO));


        return merchantDTO;
    }

    @Override
    public StoreDTO createStore(StoreDTO storeDTO) throws BusinessException {
        // 非空校验

        // 对象转换
        Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);

        // 数据保存
        storeMapper.insert(store);

        return StoreConvert.INSTANCE.entity2dto(store);
    }

    @Override
    public StaffDTO createStaff(StaffDTO staffDTO) throws BusinessException {
        // 非空

        if(isExistStaffByMobile(staffDTO.getMobile(), staffDTO.getMerchantId())){
            // 当前手机号已存在
            throw new BusinessException(CommonErrorCode.E_200203);
        }

        if(isExistStaffByUserName(staffDTO.getUsername(), staffDTO.getMerchantId())){
            throw new BusinessException(CommonErrorCode.E_200225);
        }

        // 对象转换
        Staff staff = StaffConvert.INSTANCE.dto2entity(staffDTO);

        //数据保存
        staffMapper.insert(staff);


        return StaffConvert.INSTANCE.entity2dto(staff);
    }

    @Override
    public void bindStaffToStore(Long storeId, Long staffId) throws BusinessException {
        StoreStaff storeStaff = new StoreStaff();
        storeStaff.setStaffId(staffId);
        storeStaff.setStoreId(storeId);
        storeStaffMapper.insert(storeStaff);
    }

    @Override
    public MerchantDTO queryMerchantByTenantId(Long tenantId) throws BusinessException {
        QueryWrapper<Merchant> qw = new QueryWrapper<>();
        qw.lambda().eq(Merchant::getTenantId,tenantId);
        Merchant merchant = merchantMapper.selectOne(qw);
        return MerchantCovert.INSTANCE.entity2dto(merchant);
    }

    @Override
    public PageVO<StoreDTO> queryStoreByPage(StoreDTO storeDTO, Integer pageNo, Integer pageSize) {
        // 分页
        IPage<Store> page = new Page<>(pageNo,pageSize);

        // 条件组装器

        QueryWrapper<Store> qw = new QueryWrapper<>();
        qw.lambda().eq(Store::getMerchantId,storeDTO.getMerchantId());
        IPage<Store> storeIPage = storeMapper.selectPage(page, qw);

        // 获取当前页的结果
        List<Store> records = storeIPage.getRecords();
        // 对象转换
        List<StoreDTO> storeDTOS = StoreConvert.INSTANCE.listEntity2listDto(records);

        PageVO<StoreDTO> pageVO = new PageVO<>();
        pageVO.setItems(storeDTOS);
        pageVO.setCounts(storeIPage.getTotal());
        pageVO.setPage(pageNo);
        pageVO.setPageSize(pageSize);
        return pageVO;
    }

    @Override
    public Boolean queryStoreInMerchant(Long storeId, Long merchantId) {

        QueryWrapper<Store> qw = new QueryWrapper<>();
        qw.lambda().eq(Store::getId,storeId).eq(Store::getMerchantId,merchantId);
        Integer integer = storeMapper.selectCount(qw);
        return integer>0;
    }

    @Override
    public StoreDTO queryStoreById(Long storeId) {

        Store store = storeMapper.selectById(storeId);
        return StoreConvert.INSTANCE.entity2dto(store);
    }

    /**
     * 判断同一商户下是否存在某用户名
     * @param username
     * @param merchantId
     * @return
     */
    private boolean isExistStaffByUserName(String username, Long merchantId) {
        QueryWrapper<Staff> qw = new QueryWrapper<>();
        qw.lambda().eq(Staff::getUsername,username)
                .eq(Staff::getMerchantId,merchantId);
        Integer integer = staffMapper.selectCount(qw);

        return integer>0;
    }

    /**
     * 判断同一商户下是否存在某手机号
     * @param mobile
     * @param merchantId
     * @return
     */
    private boolean isExistStaffByMobile(String mobile, Long merchantId) {
        QueryWrapper<Staff> qw = new QueryWrapper<>();
        qw.lambda().eq(Staff::getMobile,mobile)
        .eq(Staff::getMerchantId,merchantId);
        Integer integer = staffMapper.selectCount(qw);

        return integer>0;
    }
}
